<template>
  <div v-loading="goodsFormLoading">
    <el-steps :active="active" finish-status="success">
      <el-step title="基本信息" />
      <el-step title="商品描述" />
      <el-step title="规格参数" />
      <el-step title="SKU属性" />
    </el-steps>
    <el-form ref="goodsForm" :model="goodsForm" label-width="80px">
      <!-- 基本信息 -->
      <div v-show="active == 0">
        <el-row>
          <el-col :span="12">
            <el-form-item label="商品分类">
              <!-- 商品分类级联选择器 -->
              <el-cascader
                v-model="categoryIds"
                :clearable="true"
                :filterable="true"
                :options="categoryOptions"
                :props="categoryProps"
                @active-item-change="handleCategoryItemChange"
                @change="handleCategoryChange"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="商品品牌">
              <el-select v-model="goodsForm.brandId" placeholder="请选择" :props="brandProps">
                <el-option
                  v-for="brand in brandOptions"
                  :key="brand.id"
                  :label="brand.brandName"
                  :value="brand.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="商品标题">
              <el-input v-model="goodsForm.title" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="商品卖点">
              <el-input v-model="goodsForm.subTitle" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="包装清单">
              <el-input v-model="goodsForm.spuDetail.packingList" type="textarea" :rows="2" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="售后服务">
              <el-input v-model="goodsForm.spuDetail.afterService" type="textarea" :rows="2" />
            </el-form-item>
          </el-col>
        </el-row>
      </div>
      <!-- 商品描述 -->
      <div v-show="active == 1">
        <el-row>
          <el-col :span="24">
            <el-form-item label-width="0">
              <tinymce v-model="goodsForm.spuDetail.description" :height="170" aria-placeholder="请输入商品描述" />
            </el-form-item>
          </el-col>
        </el-row>
      </div>
      <!-- 规格参数 -->
      <div v-show="active == 2" style="height: 330px; overflow:auto;">
        <el-form-item v-for="specParam in genericSpecs" :key="specParam.id" :label="specParam.specParamName" label-width="140px">
          <el-input v-model="specParam.specParamValue">
            <template v-if="specParam.unit" slot="append">{{ specParam.unit }}</template>
          </el-input>
        </el-form-item>
      </div>
      <!-- SKU属性 -->
      <div v-show="active == 3" style="height: 330px; overflow:auto;">
        <el-row>
          <el-col v-for="(specParam) in specialSpecs" :key="specParam.id" :span="24">
            <el-form-item v-for="i in specParam.options.length + 1" :key="i" :label="specParam.specParamName">
              <el-input
                v-model="specParam.options[i - 1]"
                style="width: 80%"
              >
                <template v-if="specParam.unit" slot="append">{{ specParam.unit }}</template>
              </el-input>
              <i v-if="i <= specParam.options.length" class="el-icon-delete" @click="specParam.options.splice(i - 1, 1)" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-card class="box-card" shadow="false">
          <div slot="header" class="clearfix">
            <span>SKU列表</span>
          </div>
          <div>
            <el-table :data="skus" style="width: 100%">
              <el-table-column
                v-for="header in skuHeaders"
                :key="header.headerName"
                :prop="header.headerName"
                :label="header.prop"
              />
              <el-table-column label="价格">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.price" placeholder="请输入价格" />
                </template>
              </el-table-column>
              <el-table-column label="库存">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.stock" placeholder="请输入库存" />
                </template>
              </el-table-column>
              <el-table-column label="有效">
                <template slot-scope="scope">
                  <el-checkbox v-model="scope.row.enable" />
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-card>
      </div>
    </el-form>
    <div>
      <el-button style="margin-top: 12px;" @click="previous">上一步</el-button>
      <el-button style="margin-top: 12px;" @click="next">下一步</el-button>
      <el-button @click="handleCancel">取 消</el-button>
      <el-button type="primary" @click="handleSubmitGoods()">
        {{ isEdit ? '编 辑' : '保 存' }}
      </el-button>
    </div>
  </div>
</template>
<script>
import Tinymce from '@/components/Tinymce'
import { listCategoriesByParentId } from '@/api/category'
import { listBrandsByCategoryId } from '@/api/brand'
import { listSpecParamsByConds } from '@/api/spec'
import { saveOrUpdateSpu } from '@/api/goods'

export default {
  components: {
    Tinymce
  },
  props: {
    isEdit: {
      type: Boolean,
      required: true
    },
    oldGoods: {
      type: Object,
      default: function() {
        return {
          spuDetail: {}
        }
      }
    }
  },
  data() {
    return {
      goodsFormLoading: false,

      active: 0,

      categoryIds: [],
      specParams: [],
      genericSpecs: [],
      specialSpecs: [],

      categoryOptions: [
        {
          id: '',
          subCategories: []
        }
      ],
      categoryProps: {
        label: 'categoryName',
        value: 'id',
        children: 'subCategories'
      },

      brandProps: {
        label: 'brandName',
        value: 'id'
      },
      brandOptions: [],

      goodsForm: {
        id: '',
        categoryId: '',
        categoryId2: '',
        categoryId3: '',
        brandId: '',
        title: '',
        subTitle: '',
        spuDetail: {
          description: '',
          genericSpec: '',
          specialSpec: '',
          packingList: '',
          afterService: ''
        },
        skus: []
      }
    }
  },
  computed: {
    skus() {
      if (!this.specialSpecs || this.specialSpecs.length <= 0) {
        return []
      }
      // 过滤掉没有值的特有规格参数
      const specialSpecs = this.specialSpecs.filter(s => {
        if (s.options && s.options.length > 0) {
          return s
        }
      })

      // 对特有规格数组进行求笛卡尔积生成skus数组
      const skus = specialSpecs.reduce((firstValue, currentValue, currentIndex, sourceArr) => {
        const result = []
        firstValue.forEach(tmpSku => {
          currentValue.options.forEach((option, i) => {
            const sku = JSON.parse(JSON.stringify(tmpSku))
            sku[currentValue.specParamName] = { id: currentValue.id, specParamValue: option }
            sku.indexes = (sku.indexes || '') + '_' + i
            if (currentIndex === specialSpecs.length - 1) {
              sku.indexes = sku.indexes.substring(1)
              // 如果发现是最后一组，则添加价格，库存等字段
              Object.assign(sku, {
                price: 0,
                stock: 0,
                enable: false,
                images: []
              })

              // 如果是编辑，则回填sku信息
              if (this.isEdit) {
                const existSku = this.goodsForm.skuMap.get(sku.indexes)
                if (existSku) {
                  const { price, stock, enable, images } = existSku
                  Object.assign(sku, {
                    price: price,
                    stock: stock,
                    enable: enable === 1,
                    images: images ? images.split(',') : []
                  })
                }
              }
            }
            result.push(sku)
          })
        })
        return result
      }, [{}])

      return skus
    },
    skuHeaders: function() {
      if (!this.skus || this.skus.length <= 0) {
        return []
      }

      const headers = []
      Object.keys(this.skus[0]).forEach(prop => {
        if (prop !== 'indexes' &&
            prop !== 'price' &&
            prop !== 'stock' &&
            prop !== 'enable' &&
            prop !== 'images'
        ) {
          headers.push({ headerName: prop + '.specParamValue', prop })
        }
      })

      return headers
    }
  },
  watch: {
    oldGoods: {
      deep: true,
      handler(curVal, oldVal) {
        console.log('isEdit的值', this.isEdit)
        if (!this.isEdit) {
          this.resetGoodsForm()

          this.categoryIds = []
          this.specParams = []
          this.genericSpecs = []
          this.specialSpecs = []
        } else {
          this.goodsForm = JSON.parse(JSON.stringify(curVal))

          this.categoryIds.push(this.goodsForm.categoryId)
          this.categoryIds.push(this.goodsForm.categoryId2)
          this.categoryIds.push(this.goodsForm.categoryId3)

          const skuMap = new Map()
          this.goodsForm.skus.forEach(sku => {
            skuMap.set(sku.indexes, sku)
          })
          this.goodsForm.skuMap = skuMap
        }
      }
    },
    categoryIds: {
      deep: true,
      handler(curVal, oldVal) {
        if (!curVal || curVal.length <= 0) {
          return
        }

        // 根据商品分类ID查询品牌
        const categoryId = this.categoryIds[2]
        this.listBrands(categoryId)
        // 根据商品分类查询规格参数
        this.listSpecParams({ categoryId })
      }
    }
  },
  mounted() {
    // 查询商品分类
    this.listCategories()
  },
  methods: {
    previous() {
      if (this.active-- < 1) this.active = 3
    },

    next() {
      if (this.active++ > 3) this.active = 0
    },

    async listCategories(parentId) {
      const newCategoryOptions = await listCategoriesByParentId(parentId)
      if (!newCategoryOptions) {
        return
      }

      newCategoryOptions.forEach(categoryOption => {
        if (categoryOption.leaf === 0) {
          categoryOption.subCategories = []
        }
      })

      if (!parentId) {
        this.categoryOptions = newCategoryOptions
        return
      } else {
        this.fillCategoryOptions(parentId, newCategoryOptions, this.categoryOptions)
      }
    },

    /**
     * 根据商品分类查询品牌
     */
    listBrands(categoryId) {
      if (!categoryId) {
        this.brandOptions = []
        this.goodsForm.brandId = ''
        return
      }
      listBrandsByCategoryId(categoryId)
        .then(res => {
          if (!res) {
            this.brandOptions = []
            this.goodsForm.brandId = ''
            return
          }
          this.brandOptions = res
        })
        .catch(err => {
          console.log(err)
        })
    },

    /**
     * 根据条件查询规格参数
     */
    listSpecParams(params) {
      listSpecParamsByConds(params)
        .then(res => {
          if (!res) {
            return
          }

          this.specParams = res
          this.filterSpecParams(res)
        })
        .catch(err => {
          this.$message.error('根据条件查询规格参数失败 ' + err)
        })
    },

    /**
     * 重置商品表单
     */
    resetGoodsForm() {
      Object.assign(this.goodsForm, {
        id: '',
        categoryId: '',
        categoryId2: '',
        categoryId3: '',
        brandId: '',
        title: '',
        subTitle: '',
        spuDetail: {
          description: '',
          genericSpec: '',
          specialSpec: '',
          packingList: '',
          afterService: ''
        },
        skus: []
      })
    },

    /**
     * 选择商品分类项后查询其下级列表
     */
    async handleCategoryItemChange(val) {
      if (!val) {
        return
      }
      const parentId = val[val.length - 1]
      await this.listCategories(parentId)
    },

    /**
     * 选择商品分类
     */
    handleCategoryChange(categoryIds) {
      // 商品分类ID
      const categoryId = categoryIds[categoryIds.length - 1]
      // 根据商品分类ID查询品牌
      this.listBrands(categoryId)
      // 根据商品分类查询规格参数
      this.listSpecParams({ categoryId })
    },

    /**
     * 删除一个属性输入行
     */
    handleDeleteSpecialParam(specialParamId) {
      let index = -1
      for (let i = 0; i < this.specialSpecs.length; i++) {
        if (this.specialSpecs[i].id === specialParamId) {
          index = i
          break
        }
      }
      if (index !== -1) {
        this.specialSpecs.splice(index, 1)
      }
    },

    /**
     * 保存/编辑商品
     */
    handleSubmitGoods() {
      this.generateCategoryData()
      this.generateGenericSpecsData()
      this.generateSpecialSpecsData()
      this.generateSkusData()

      this.goodsFormLoading = true
      saveOrUpdateSpu(this.goodsForm, this.isEdit ? 'PUT' : 'POST')
        .then(res => {
          this.$message({
            message: (this.isEdit ? '编辑' : '保存') + '商品成功！',
            type: 'success'
          })
          this.$emit('goodsDialogClose')
        })
        .catch(err => {
          this.$message.error((this.isEdit ? '编辑' : '保存') + '商品失败！', err)
        })
        .then(() => {
          this.goodsFormLoading = false
        })
    },

    handleCancel() {
      this.$emit('goodsDialogClose')
    },

    /**
     * 根据parentId递归查询对应的CategoryOption
     */
    fillCategoryOptions(parentId, newCategoryOptions, categoryOptions) {
      if (!newCategoryOptions || !categoryOptions) {
        return
      }

      for (let i = 0; i < categoryOptions.length; i++) {
        if (categoryOptions[i].id === parentId) {
          categoryOptions[i].subCategories = newCategoryOptions
          return
        }
        this.fillCategoryOptions(parentId, newCategoryOptions, categoryOptions[i].subCategories)
      }
    },

    /**
     * 过滤出通用/特有规格数组
     */
    filterSpecParams(specParams) {
      if (!specParams) {
        return []
      }

      let tmpGenericSpecs = []
      let tmpSpecialSpecs = []
      if (this.isEdit) {
        tmpGenericSpecs = JSON.parse(this.goodsForm.spuDetail.genericSpec)
        tmpSpecialSpecs = JSON.parse(this.goodsForm.spuDetail.specialSpec)
      }

      const newGenericSpecs = []
      const newSpecialSpecs = []
      specParams.forEach(({ id, specParamName, isGeneric, isNumric, unit }) => {
        if (isGeneric === 1) {
          const genericSpec = { id, specParamName, isNumric, unit }
          if (this.isEdit) {
            genericSpec.specParamValue = tmpGenericSpecs[id]
          }
          newGenericSpecs.push(genericSpec)
        } else {
          const specialSpec = { id, specParamName, options: [] }
          if (this.isEdit) {
            specialSpec.options = (tmpSpecialSpecs[id] || [])
          }
          newSpecialSpecs.push(specialSpec)
        }
      })

      this.genericSpecs = newGenericSpecs
      this.specialSpecs = newSpecialSpecs
    },

    /**
     * 生成商品分类数据
     */
    generateCategoryData() {
      if (!this.categoryIds) {
        this.goodsForm.categoryId = ''
        this.goodsForm.categoryId2 = ''
        this.goodsForm.categoryId3 = ''
        return
      }

      this.goodsForm.categoryId = this.categoryIds[0]
      this.goodsForm.categoryId2 = this.categoryIds[1]
      this.goodsForm.categoryId3 = this.categoryIds[2]
    },

    /**
     * 生成通用规格参数数据
     */
    generateGenericSpecsData() {
      if (!this.genericSpecs) {
        return {}
      }

      const tmpGenericSpec = {}
      for (let i = 0; i < this.genericSpecs.length; i++) {
        if (!this.genericSpecs[i].specParamValue) {
          continue
        }
        tmpGenericSpec[this.genericSpecs[i].id] = this.genericSpecs[i].specParamValue
      }

      this.goodsForm.spuDetail.genericSpec = JSON.stringify(tmpGenericSpec)
    },

    /**
     * 生成特有规格属性数据
     */
    generateSpecialSpecsData() {
      if (!this.specialSpecs) {
        return
      }

      const tmpSpecialSpecs = {}
      this.specialSpecs.forEach(specialSpec => {
        tmpSpecialSpecs[specialSpec.id] = specialSpec.options
      })

      this.goodsForm.spuDetail.specialSpec = JSON.stringify(tmpSpecialSpecs)
    },

    /**
     * 生成skus数据
     */
    generateSkusData() {
      if (!this.skus) {
        return
      }

      const skus = this.skus
        .filter((sku, index, srcArr) => sku.enable)
        .map(({ price, stock, enable, images, indexes, ...rest }) => {
          const title = this.goodsForm.title + ' ' + Object.values(rest).map(specialParam => specialParam.specParamValue).join(' ')
          const ownSpec = {}
          Object.values(rest).forEach(specialParam => {
            ownSpec[specialParam.id] = specialParam.specParamValue
          })

          return {
            title, // 基本属性
            price, // 价格需要格式化
            stock,
            indexes,
            enable: enable ? 1 : 0,
            images: images ? images.join(',') : '', // 图片
            ownSpec: JSON.stringify(ownSpec) // 特有规格参数
          }
        })

      this.goodsForm.skus = skus
    }
  }
}
</script>
<style scoped>
</style>>
